import htw.io.*;
import htw.io.exceptions.*;
import studentUeb.*;
import studentUeb.exceptions.*;
import htw.exceptions.*;
import htw.student.*;
import studentUeb.StudentIO;
import de.htw.saarland.stl.Stdin;

/**
 * Interaktive Testklasse fuer StudentList
 * 
 * @author Steffen Schuhmann, Andreas Dier 
 * @version 0.4
 */
public class StudentDialog
{
    //Laenge der Trennzeile
    private final int       LAENGE                 = 80;
    
    private static final String SAVEPLACE          = "Wohin wollen sie speichern?: "; 
    
    
    private StringBuffer    hilfeDialog            = new StringBuffer();
    private StudentQueue    aktuelleListe          = new StudentQueue();
    private String          fileName               = null; 

    // Objektinitialisierungsblock
    private String menu(){
        // Erstellen des Hilfedialogs
        hilfeDialog.append(StudentListDialogEnum.ADD_STUDENT.getHD());
        hilfeDialog.append(StudentListDialogEnum.ADD_GROUP.getHD());
        hilfeDialog.append(StudentListDialogEnum.DEL_STUDENT.getHD());
        hilfeDialog.append(StudentListDialogEnum.SIZE.getHD());
        hilfeDialog.append(StudentListDialogEnum.SAVE.getHD());
        hilfeDialog.append(StudentListDialogEnum.LOAD.getHD());
        hilfeDialog.append(StudentListDialogEnum.CLONE.getHD());
        hilfeDialog.append(StudentListDialogEnum.APPEND.getHD());
        hilfeDialog.append(StudentListDialogEnum.EQUALS.getHD());
        hilfeDialog.append(StudentListDialogEnum.HELP.getHD());
        hilfeDialog.append(StudentListDialogEnum.END.getHD());
        
        return hilfeDialog.toString();
    }

    /**
     * Gibt  eine Trennzeile aus.
     */
    private void trennZeile() {
        for(int i = 1; i <= LAENGE; i++){
            System.out.print("*");
        }
        System.out.println();
    }

    /**
     * Hauptschleife
     */
    public void start(){
        String funktion = new String();
        while(!funktion.equalsIgnoreCase(StudentListDialogEnum.END.getCommand())){
            try{
                funktion = einlesenFunktion();
                trennZeile();
                ausfuehrenFunktion(funktion);
            } catch(AssertionError e) {
                System.out.println(e);
                e.printStackTrace();
            } catch(Exception e) {
                System.out.println(e);
                e.printStackTrace();
            }    
        }
    }

    /**
     * Gibt eine Trennzeile aus und fragt nach einer Befehleingabe
     * 
     * @return Der eingegebene Befehl
     */
    private String einlesenFunktion(){
        System.out.print(""+menu());
        System.out.println("");
        trennZeile();
        System.out.print("");
        return Stdin.readString();
    }

    /**
     * Auswerten des eingegebenen Befehls und ausfuehren der damit gekoppelten Funktion.
     *
     * @param funktion das auszuwertende Kommando
     */
    private void ausfuehrenFunktion(String funktion) throws Exception{
        if(StudentListDialogEnum.ADD_STUDENT.getCommand().equalsIgnoreCase(funktion)) {
            newStudent();
        } else if (StudentListDialogEnum.ADD_GROUP.getCommand().equalsIgnoreCase(funktion)) {
            newStudentGroup();
        } else if (StudentListDialogEnum.DEL_STUDENT.getCommand().equalsIgnoreCase(funktion)) {
            removeStudent();
        } else if (StudentListDialogEnum.SIZE.getCommand().equalsIgnoreCase(funktion)) {
            printSize();
        } else if (StudentListDialogEnum.SAVE.getCommand().equalsIgnoreCase(funktion)) {
            fileName = Stdin.readString();
            saveList();
        } else if (StudentListDialogEnum.LOAD.getCommand().equalsIgnoreCase(funktion)) {
            loadList();
        } else if (StudentListDialogEnum.HELP.getCommand().equalsIgnoreCase(funktion)) {
            hilfeDialog();
        }

    }
    
    /**
     * Loeschen eines Objektes vom Typ Student 
     */
    public void removeStudent() throws htw.exceptions.NoListException{
        
        aktuelleListe.remove();

    }
    
    /**
     * Anlegen eines neuen Objektes vom Typ Student und anhaengen an das ende der Warteliste
     */
    public void newStudent() throws htw.exceptions.NoListException, StudentAlreadyInListException{
        
        Student newStudent = new Student();
        
        newStudent.eingeben();
        aktuelleListe.add(newStudent);

    }
    
    /**
     * Anlegen mehrerer Studentenobjekte und anfuegen an das Ende der Liste.
     */ 
    public void newStudentGroup() throws htw.exceptions.NoListException, StudentAlreadyInListException{
        int count = 0;
        
        while(count <= 0) {
            count = Stdin.readInt("Wie viele Studenten sollen angelegt werden: ");
        }
        
        for(int i = 1; i <= count; i++) {
            System.out.print(count + ". Student");
            newStudent();
        }
    }

    /**
     * Loeschen des letzten Student Objektes der Warteliste
     */
    public void delStudent(){
        try {
            aktuelleListe.remove();
        } catch(Exception e) {}
    }

    /**
     * Speichern der Warteschlange
     */
    public void saveList() throws Exception {
        
        String fileName;
        String antwort = null;
        boolean override = false;
        
        System.out.println("Bitte den Speicherpfad angeben: ");
        fileName = Stdin.readString();
        
        System.out.println("Sollte eine vorhandene datei ueberschrieben werden? (ja/nein)");
        
        while(antwort.equalsIgnoreCase("ja") || antwort.equalsIgnoreCase("nein")) {
            antwort = Stdin.readString("(ja/nein)");
        }
        
        if (antwort.equalsIgnoreCase("ja"))
            override = true;
        if (antwort.equalsIgnoreCase("nein"))
            override = false;

        try {
            StudentIO.saveObject(aktuelleListe, fileName, override);
        } catch(StringIsEmptyException sie) {
            System.out.println("Es muss ein Dateiname angegeben werden!!");
        }catch(FileAlreadyExistsException fae) {
            String answer;
            boolean choosen = false;
            System.out.println("Es existiert bereits eine Datei mit dem Namen, soll diese Datei ueberschrieben werden? (J/N))");
            while(!choosen) {
                answer = Stdin.readString();
                
                if(Strings.JA.equalsIgnoreCase(answer)) {
                    StudentIO.saveObject(aktuelleListe, fileName, true);
                    choosen = true;
                }
                
                if(Strings.NEIN.equalsIgnoreCase(answer)) {
                    System.out.println("Der vorgang wurde abgebrochen");
                    choosen = true;
                }
            }
        }catch(CanNotWriteObjectException cnw) {
            System.out.println("Das Objekt konnte nicht gespeichert werden!");
            System.out.println(cnw.getMessage());
        }finally {}
    }

       
    /**
     * Laden einer Warteschlange
     */
    public StudentQueue loadList() throws Exception {
        String fileName;
        StudentQueue newQueue = null;
        
        fileName = Stdin.readString("Bitte Pfad und Dateiname angeben: ");

        try {
            newQueue = (StudentQueue) ObjectIO.loadObject(fileName);
        }catch(StringIsEmptyException siee) {
            System.out.println("Der Dateiname darf nicht leer sein!");
        }catch(CanNotLoadObjectException cnlo){
            System.out.println("Fehler beim laden der Liste!");
        }catch(ClassNotFoundException cnf) {
            System.out.println("Objekt ist kein ListenObjekt");
        }

        return newQueue;
    }
    
    /**
     * Gibt die aktuelle Warteliste aus.
     */
    public void printList() {
        System.out.println(aktuelleListe.toString());
    }
    
    public void printSize() {
        System.out.println(aktuelleListe);
    }
    
    public void cloneList() {
        
    }
    
    public void equals() {
        
        StudentQueue loadedList = null;
        try {
            loadedList = loadList();
        } catch(Exception e) {
            System.out.println("Abbruch!");
        }
        
        if(loadedList != null) {
            try {
                aktuelleListe.equals(loadedList);
            } catch(NoListException nle) {
                System.out.println(nle.getMessage());
            }
        }
    }
    
    public void append() {
        StudentQueue toAppend = null;
        try {
            toAppend = loadList();
        } catch(Exception e) {
            System.out.println("Abbruch!");
        }
        
        if (toAppend != null) {
            try {
                aktuelleListe.append(toAppend);
            } catch (NoListException nle) {
                System.out.println(nle.getMessage());
            }
        }
    }

    /**
     * Druckt einen Hilfedialog, der alle Befehlsmoeglichkeiten ausgibt.
     */
    public void hilfeDialog() {
        trennZeile();
        System.out.println(hilfeDialog.toString());
        trennZeile();
    } 

    /**
     * Main-Methode zum Erzeugen des ArrayDialog-Objektes und
     * zum Anstarten des Testschleifea
     */
    public static void main(String[] args){
        StudentDialog app = new StudentDialog();
        app.start();
    }

}
